#ifndef __FORMATEDMUTILINESTRING_H
#define __FORMATEDMUTILINESTRING_H

#include <cstring>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

class FormatedMutilineString
{	
	public:char* dataBuffer;	//被格式化的原始字符串数据副本 
	
	private:size_t colCount;	//列数
	//行数通过 lineEntries.size() 获取 
	
	public:typedef vector<char*> Lines;
	public:typedef Lines::const_iterator const_iterator;
	public:typedef Lines::const_reverse_iterator const_reverse_iterator;
	private:Lines* lineEntries;		//格式化后每行入口（运用指针以支持移动语义） 
	
	public:FormatedMutilineString
	(const string& str,	const size_t formatLengthPerLine):
		dataBuffer(nullptr),
		colCount(formatLengthPerLine),
		lineEntries(nullptr)
	{
		dataBuffer  = new char[str.length() + 1];
		lineEntries = new Lines;
		
		//拷贝副本 
		memcpy(dataBuffer, str.c_str(), str.length() + 1);
		
		#define initNewLine(linePointer) {\
			lineEntries->push_back(new char[colCount * 3 + 2]);\
			linePointer = lineEntries->back();\
		}
		
		#define newLine(linePointer, columnIndex, colMax) {\
			if(linePointer != nullptr) linePointer[columnIndex] = '\0';\
			initNewLine(linePointer);\
			columnIndex = 0;\
			colMax = colCount;\
		}
			
		char* currentLine = nullptr;
		size_t currentColumn = 0;
		
		//初始状态下新增一行
		initNewLine(currentLine);
		
		size_t currColMaxLen = colCount;
		
		for	//对于副本中每一个字符
		(
			size_t current = 0;
			dataBuffer[current] != '\0';
			//++current
		)
		{
			if(static_cast<unsigned char>(dataBuffer[current]) <= 127) switch(dataBuffer[current])
			{
				case '\n':
					while(currentColumn < currColMaxLen) currentLine[currentColumn++] = ' ';
					newLine(currentLine, currentColumn, currColMaxLen);
					++current;
					break;
					
				case '\t':
					for(int i = 0, j = 4 - (currentColumn % 4); i < j; ++i)
					{
						currentLine[currentColumn++] = ' ';
						if(currentColumn == currColMaxLen) newLine(currentLine, currentColumn, currColMaxLen);
					}
					++current;
					break;
					
				default:
					currentLine[currentColumn++] = dataBuffer[current];
					if(currentColumn == currColMaxLen) newLine(currentLine, currentColumn, currColMaxLen);
					++current;
			}
			else if(static_cast<unsigned char>(dataBuffer[current]) < 224)//内存占用2字节，宽1格的字符
			{
				++currColMaxLen;
				if(currentColumn + 2 > currColMaxLen)
				{
					if(currentColumn + 1 <= currColMaxLen) currentLine[currentColumn++] = ' ';
					newLine(currentLine, currentColumn, currColMaxLen);
					++currColMaxLen;
				}
				
				currentLine[currentColumn++] = dataBuffer[current++];
				currentLine[currentColumn++] = dataBuffer[current++];
				
				if(currentColumn == currColMaxLen)
				{
					//currentLine[currentColumn++] = ' ';
					newLine(currentLine, currentColumn, currColMaxLen);
				}
			}
			else if(static_cast<unsigned char>(dataBuffer[current]) >= 224)//汉字
			{
				++currColMaxLen;
				if(dataBuffer[current+1] == 189  &&  dataBuffer[current+2] == 128) ++currColMaxLen;
				if(currentColumn + 3 > currColMaxLen)
				{
					if(currentColumn + 1 <= currColMaxLen) currentLine[currentColumn++] = ' ';
					newLine(currentLine, currentColumn, currColMaxLen);
					++currColMaxLen;
					if(dataBuffer[current+1] == 189  &&  dataBuffer[current+2] == 128) ++currColMaxLen;
				}
				
				currentLine[currentColumn++] = dataBuffer[current++];
				currentLine[currentColumn++] = dataBuffer[current++];
				currentLine[currentColumn++] = dataBuffer[current++];
				
				if(currentColumn == currColMaxLen)
				{
					//currentLine[currentColumn++] = ' ';
					newLine(currentLine, currentColumn, currColMaxLen);
				}
			}
		}
		
		while(currentColumn < currColMaxLen)
		{
			currentLine[currentColumn++] = ' ';
		}
		
		currentLine[currentColumn] = '\0';
	}
	
	public:~FormatedMutilineString(void)
	{
		if(lineEntries != nullptr)
		{
			for
			(
				const_iterator eachLine = lineEntries->cbegin();
				eachLine != lineEntries->end();
				++eachLine
			)	delete *eachLine;
			
			delete lineEntries;
		}
		
		if(dataBuffer != nullptr) delete dataBuffer;
	}
	
	//禁用拷贝 
	public:FormatedMutilineString(const FormatedMutilineString& another) = delete;
	public:FormatedMutilineString& operator = (const FormatedMutilineString& another) = delete;
	
	//移动拷贝 
	public:FormatedMutilineString(FormatedMutilineString && another) noexcept:
		dataBuffer(another.dataBuffer),
		colCount(another.colCount),
		lineEntries(another.lineEntries)
	{
		another.dataBuffer = nullptr;
		another.colCount = 0;
		another.lineEntries = nullptr;
	}
	
	//移动赋值 
	public:FormatedMutilineString& operator = (FormatedMutilineString && another) noexcept
	{
		dataBuffer = another.dataBuffer;
		colCount = another.colCount;
		lineEntries = another.lineEntries;
		
		another.dataBuffer = nullptr;
		another.colCount = 0;
		another.lineEntries = nullptr;
		
		return *this;
	}
	
	//获取行数 
	public:size_t getLineCount(void) const 
	{
		if(lineEntries != nullptr) return lineEntries->size();
		else return 0;
	}
	
	//获取某行 
	public:const char* getLine(size_t index) const
	{
		if(lineEntries != nullptr) return (*lineEntries)[index];
		else return nullptr;
	}
	public:const char* operator [] (size_t index) const
	{
		return getLine(index);
	}
	
	//获取最大列数
	public:size_t getMaxColumnCount(void) const
	{
		return colCount;
	}
	
	//遍历行迭代器 
	public:const_iterator cbegin(void) const
	{
		if(lineEntries != nullptr) return lineEntries->cbegin();
		else return const_iterator();
	}
	public:const_iterator cend(void) const
	{
		if(lineEntries != nullptr) return lineEntries->cend();
		else return const_iterator();
	}
	public:const_reverse_iterator crbegin(void) const
	{
		if(lineEntries != nullptr) return lineEntries->crbegin();
		else return const_reverse_iterator();
	}
	public:const_reverse_iterator crend(void) const
	{
		if(lineEntries != nullptr) return lineEntries->crend();
		else return const_reverse_iterator();
	}
	
	//输出
	public:friend ostream& operator << (ostream& stream, const FormatedMutilineString& fms)
	{
		bool firstLine = true;
		
		for
		(
			const_iterator i = fms.cbegin();
			i != fms.cend();
			++i
		)
		{
			if(!firstLine) cout<<endl;
			stream<<*i;
			firstLine = false;
		}
		
		return stream;
	}
	
	//比较原始字符串副本 
	public:bool operator == (const FormatedMutilineString& another) const
	{
		if(dataBuffer != nullptr  &&  another.dataBuffer != nullptr)
		{
			return strcmp(dataBuffer, another.dataBuffer) == 0;
		}
		else return false;
	}
	
	public:bool operator != (const FormatedMutilineString& another) const
	{
		if(dataBuffer != nullptr  &&  another.dataBuffer != nullptr)
		{
			return strcmp(dataBuffer, another.dataBuffer) != 0;
		}
		else return false;
	}
	
	public:bool operator >= (const FormatedMutilineString& another) const
	{
		if(dataBuffer != nullptr  &&  another.dataBuffer != nullptr)
		{
			return strcmp(dataBuffer, another.dataBuffer) >= 0;
		}
		else return false;
	}
	
	public:bool operator <= (const FormatedMutilineString& another) const
	{
		if(dataBuffer != nullptr  &&  another.dataBuffer != nullptr)
		{
			return strcmp(dataBuffer, another.dataBuffer) <= 0;
		}
		else return false;
	}
	
	public:bool operator > (const FormatedMutilineString& another) const
	{
		if(dataBuffer != nullptr  &&  another.dataBuffer != nullptr)
		{
			return strcmp(dataBuffer, another.dataBuffer) > 0;
		}
		else return false;
	}
	
	public:bool operator < (const FormatedMutilineString& another) const
	{
		if(dataBuffer != nullptr  &&  another.dataBuffer != nullptr)
		{
			return strcmp(dataBuffer, another.dataBuffer) < 0;
		}
		else return false;
	}
	
};
#endif
/*
int main(void)
{
	string s = "likuh flkiushdefluh wa weflkuybgeflku	;oih\n\tasdn;o\n\n\tasdasd	\nseasfseg seafawesf s\n\n\ndwadwqwad";
	FormatedMutilineString fms(s, 6);
	
	cout<<fms.dataBuffer<<endl<<endl<<endl;
	
	cout<<fms<<flush;
	
	cin.get();
	
	return 0;
}
*/
